package com.hzbc.faceattendance.aop;
/**
 * @author junmu
 * @time 2025-07-25 14:14:01
 */

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hzbc.faceattendance.model.SystemLog;
import com.hzbc.faceattendance.repository.LogRepository;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;

@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class LoggingAspect {
    private final LogRepository logRepository;

    private final ObjectMapper objectMapper; // 新增注入字段

    @Around("execution(* com.hzbc.faceattendance.controller..*(..))")
    public Object logController(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        SystemLog localLog = new SystemLog();
        localLog.setLogTime(LocalDateTime.now());
        localLog.setMethod(joinPoint.getSignature().toShortString());
        localLog.setLoggerName(joinPoint.getSignature().getDeclaringTypeName());
        try {
            localLog.setParams(objectMapper.writeValueAsString(joinPoint.getArgs()));
            log.info("请求方法:{},参数: {}", localLog.getMethod(), localLog.getParams());
        } catch (JsonProcessingException e) {
            localLog.setParams("参数序列化失败: " + e.getMessage());
        }

//        if(authentication != null && authentication.isAuthenticated()) {
//            log.setUserId(String.valueOf(authentication.getPrincipal()));
//        }
        localLog.setIpAddress(request.getRemoteAddr());

        try {
            Object result = joinPoint.proceed();
            if(joinPoint ==null || joinPoint.getSignature() ==null || joinPoint.proceed() == null ) {
                return result;
            }
            localLog.setLogLevel("INFO");
            try {
                String resultJson = objectMapper.writeValueAsString(result);
                localLog.setMessage("操作成功 - 返回结果: " + truncateString(resultJson, 200)); // 截断前200字符防止过长
                log.info("操作成功 - 返回结果: " + truncateString(resultJson, 200)); // 截断前200字符防止过长
            } catch (JsonProcessingException e) {
                log.error("操作失败 - 结果序列化失败", e);
                localLog.setLogLevel("ERROR");
                localLog.setMessage("操作失败 - 结果序列化失败");
            }
            return result;
        } catch (Exception e) {
            log.error("操作失败 - 原因: {}", e.getMessage(), e);
            localLog.setLogLevel("ERROR");
            localLog.setException(ExceptionUtils.getStackTrace(e));
            localLog.setMessage("操作失败 - 原因: " + e.getMessage()); // 新增错误原因
            throw e;
        } finally {
            logRepository.saveAsync(localLog);
        }
    }

    private String truncateString(String input, int maxLength) {
        if (input == null) return "";
        return input.length() > maxLength ? input.substring(0, maxLength) + "..." : input;
    }
}